package com.ifonly.upload;

import com.ifonly.config.Configuration;
import com.ifonly.upload.cos.MultipartRequest;
import com.ifonly.upload.cos.multipart.DefaultFileRenamePolicy;
import com.ifonly.upload.cos.multipart.FileRenamePolicy;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author <a href="mailto:ifonlymaster@163.com">ifonly</a>
 * @version 1.0 2015-12-14 09:01
 * @since JDK 1.6
 */
public class CosMultipartServletRequest extends MultipartServletRequest {
    static FileRenamePolicy fileRenamePolicy = new DefaultFileRenamePolicy();
    static Configuration cfg = Configuration.getInstance();

    private MultipartRequest multipartRequest;
    private Map<String, IFile[]> iFileMap;

    public CosMultipartServletRequest(HttpServletRequest request, String saveDirectory, int maxPostSize, String encoding) {
        super(request);
        wrapMultipartRequest(saveDirectory, maxPostSize, encoding);
    }

    public CosMultipartServletRequest(HttpServletRequest request, String saveDirectory, int maxPostSize) {
        super(request);
        wrapMultipartRequest(saveDirectory, maxPostSize, null);
    }

    public CosMultipartServletRequest(HttpServletRequest request, String saveDirectory) {
        super(request);
        wrapMultipartRequest(saveDirectory, cfg.getMaxUploadSize(), cfg.getEncoding());
    }

    public CosMultipartServletRequest(HttpServletRequest request) {
        super(request);
        wrapMultipartRequest(cfg.getUploadSaveDir(), cfg.getMaxUploadSize(), cfg.getEncoding());
    }



    private void wrapMultipartRequest(String saveDirectory, int maxPostSize, String encoding) {
        if (request == null) {
            throw new IllegalArgumentException("param request can not be null");
        }
        saveDirectory = handleSaveDirectory(saveDirectory);

        iFileMap = new HashMap<String, IFile[]>();

        try {
            multipartRequest = new MultipartRequest(request, saveDirectory, maxPostSize, encoding, fileRenamePolicy);
            Enumeration files = multipartRequest.getFileNames();
            while (files.hasMoreElements()) {
                String name = (String)files.nextElement();
                String[] filesystemNames = multipartRequest.getFilesystemNames(name);
                if (filesystemNames != null && filesystemNames.length > 0) {
                    for (String filesystemName : filesystemNames) {
                        if (filesystemName != null) {
                            String originalFileName = multipartRequest.getOriginalFileName(name);
                            String contentType = multipartRequest.getContentType(name);
                            IFile iFile = new IFile(name, saveDirectory, originalFileName, filesystemName, contentType);
                            if (isSafeFile(iFile)) {
                                IFile[] fileList = iFileMap.get(iFile.getParameter());
                                if (fileList == null) {
                                    fileList = new IFile[]{iFile};
                                    iFileMap.put(iFile.getParameter(), fileList);
                                } else {
                                    IFile[] tmp = new IFile[fileList.length + 1];
                                    System.arraycopy(fileList, 0, tmp, 0, fileList.length);
                                    tmp[tmp.length - 1] = iFile;
                                    fileList = tmp;
                                    iFileMap.put(iFile.getParameter(), fileList);
                                }
                            }
                        }
                    }
                }


            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Enumeration<String> getFileNames() {
        return multipartRequest.getFileNames();
    }

    @Override
    public File getFile(String name) {
        IFile[] iFiles = iFileMap.get(name);
        if (iFiles == null || iFiles.length == 0) {
            return null;
        }
        return iFiles[iFiles.length - 1].getFile();
    }

    @Override
    public File[] getFiles(String name) {
        IFile[] iFiles = iFileMap.get(name);
        if (iFiles == null || iFiles.length == 0) {
            return null;
        }
        File[] results = new File[iFiles.length];
        for (int i = 0, len = iFiles.length; i < len; i++) {
            results[i] = iFiles[i].getFile();
        }
        return results;
    }

    @Override
    public Enumeration<String> getParameterNames() {
        return multipartRequest.getParameterNames();
    }

    @Override
    public String getParameter(String name) {
        return multipartRequest.getParameter(name);
    }

    @Override
    public String[] getParameterValues(String name) {
        return multipartRequest.getParameterValues(name);
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> map = new HashMap<String, String[]>();
        Enumeration e = getParameterNames();
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
            map.put(name, multipartRequest.getParameterValues(name));
        }
        return map;
    }

    @Override
    public Map<String, IFile[]> getFileMap() {
        return iFileMap;
    }
}
